/*
 Copyright 2007 Ole Rogeberg

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */
package org.lifeyears.web.interceptor;

import org.lifeyears.web.action.AbstractLifeyearsAction;
import org.lifeyears.web.resulttype.RedirectAndKeepMessagesResult;
import org.lifeyears.web.resulttype.ResultValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
import com.opensymphony.xwork2.interceptor.ParametersInterceptor;
import com.opensymphony.xwork2.util.ValueStack;

/**
 * Struts interceptor which extracts errors, fieldErrors, messages and parameters sat by
 * RedirectAndKeepMessagesResult.
 *
 * @see RedirectAndKeepMessagesResult
 *
 * @author Aleksander Blomskøld
 *
 */
public class ExtractMessagesInterceptor
    extends ParametersInterceptor
    implements Interceptor

{
    private final Logger log = LoggerFactory.getLogger( this.getClass() );

    @Override
    public String intercept( final ActionInvocation invocation )
        throws Exception
    {

        final ActionContext invocationContext = invocation.getInvocationContext();
        final String actionName = invocationContext.get( ActionContext.ACTION_NAME ).toString();
        final Object res = invocationContext.getSession().get( RedirectAndKeepMessagesResult.getSessionKey( actionName ) );

        if ( res != null )
        {
            // we have an object - should be a ResultValue
            if ( res instanceof ResultValue )
            {
                final ResultValue resultValue = (ResultValue) res;

                // get action from invocation
                // feed with errors and messages
                final Object actionObject = invocation.getAction();

                if ( actionObject instanceof AbstractLifeyearsAction )
                {
                    final AbstractLifeyearsAction abstractLifeyearsAction = (AbstractLifeyearsAction) actionObject;
                    final ValueStack valueStack = invocationContext.getValueStack();

                    if ( resultValue.getErrors() != null )
                    {
                        abstractLifeyearsAction.setActionErrors( resultValue.getErrors() );
                    }
                    if ( resultValue.getMessages() != null )
                    {
                        abstractLifeyearsAction.setActionMessages( resultValue.getMessages() );
                    }
                    if ( resultValue.getFieldErrors() != null )
                    {
                        abstractLifeyearsAction.setFieldErrors( resultValue.getFieldErrors() );
                    }

                    // extract the parameters and use setParameters of the super-class
                    if ( resultValue.getParameters() != null )
                    {
                        super.setParameters( invocation.getAction(), valueStack, resultValue.getParameters() );
                    }

                }
                else
                {
                    log.warn( "ActionObject of wrong type: {}", actionObject );
                }

            }
            else
            {
                log.warn( "Result in session of wrong type: {}", res );
            }
            invocationContext.getSession().remove( RedirectAndKeepMessagesResult.getSessionKey( actionName ) );
        }

        return invocation.invoke();
    }

}
